//
// Created by Lemon on 2024/8/30.
//

#include "Tracker.h"

#define REC_SIGN SIGUSR2

/// 游离的对象...
static pthread_t mainThread = 0;

void Tracker::trackerActionWithSignum(int signum, siginfo_t *info, void *invokeContext) {
    int deep = STACK_DEEP;
    /// this can get ios fp....
    ucontext_t *uc = (ucontext_t *) invokeContext;
    uint64_t fp = uc->uc_mcontext->__ss.__fp;
    uint64_t lr = uc->uc_mcontext->__ss.__lr;
    int backline = 0;
    std::stringstream ss;
    ss << "Architecture: arm64-ios" << std::endl;
    ss << "isolate_instructions: " << std::hex << baseIsolateInstructions << ", "
       << "vm_instructions: "
       << std::hex << baseVmInstructions << std::endl;
    while (fp && lr && deep--) {

        if (*((uint64_t *) fp) <= fp) {
            break;
        }

        if (!(fp + 8) || !(uint64_t) fp) {
            break;
        }

        ss << transformFormat(backline, lr, baseIsolateInstructions)
           << std::endl;

        lr = *((uint64_t *) (fp + 8));
        fp = *((uint64_t *) fp);
    }
    /// report ss, ss is string...
    
}

void Tracker::track() {
    if (mainThread) {
        pthread_kill(mainThread, REC_SIGN);
    }
}

void Tracker::registerSignalListener() {
    actionNew.sa_sigaction = trackerActionWithSignum;
    sigemptyset(&actionNew.sa_mask);
    /// 通过这个 sa_flags 可以获取到对应的信息，之后根据线程的上下文信息，获取对应的堆栈信息
    actionNew.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
    if (sigaction(REC_SIGN, &actionNew, nullptr) == 0) {
        isRegister = 1;
    } else {
        isRegister = 0;
        mainThread = 0;
    }
}

void Tracker::setBaseIsolateInstructions(uint64_t isolateInstructions, uint64_t vmInstructions) {
    baseIsolateInstructions = isolateInstructions;
    baseVmInstructions = vmInstructions;
}

void Tracker::setStackCallback(void (*stackCallback)(const std::string&)) {
    reportCallback = stackCallback;
}

void Tracker::unregisterSignalListener() {
    if (isRegister) {
        sigaction(SIGUSR2, nullptr, &actionNew);
    }
    mainThread = 0;
}